package com.hzsparrow.ai.service;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.ai.vectorstore.filter.Filter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hzsparrow.ai.entity.Document;
import com.hzsparrow.ai.entity.KnowledgeBase;
import com.hzsparrow.ai.mapper.DocumentMapper;
import com.hzsparrow.ai.util.DocumentSplitSaveUtil;
import com.hzsparrow.ai.config.AIModelInitService;

/**
 * 文档服务实现类
 */
@Service
public class DocumentServiceImpl extends ServiceImpl<DocumentMapper, Document> implements DocumentService {

    @Autowired
    private AIModelInitService aiModelInitService;

    @Autowired
    private KnowledgeBaseService knowledgeBaseService;

    @Override
    public Document saveDocument(Document document) {
        // 设置创建和更新时间
        LocalDateTime now = LocalDateTime.now();
        document.setCreateTime(now);
        document.setUpdateTime(now);

        // 保存文档到数据库
        this.save(document);

        // 如果关联了知识库，则保存文档到向量数据库
        if (document.getKnowledgeBaseId() != null) {
            saveDocumentToVectorStore(document);
        }

        return document;
    }

    /**
     * 将文档保存到向量数据库
     *
     * @param document 文档对象
     */
    private void saveDocumentToVectorStore(Document document) {
        try {
            // 获取当前默认向量存储
            VectorStore vectorStore = aiModelInitService.getDefaultVectorStore();
            if (vectorStore == null) {
                System.err.println("无法保存文档到向量数据库：默认向量存储未初始化");
                return;
            }

            // 获取关联的知识库
            KnowledgeBase knowledgeBase = knowledgeBaseService.getKnowledgeBase(document.getKnowledgeBaseId());
            if (knowledgeBase == null) {
                System.err.println("无法保存文档到向量数据库：找不到关联的知识库，ID: " + document.getKnowledgeBaseId());
                return;
            }

            // 获取向量索引名称
            String indexName = knowledgeBase.getVectorIndexName();
            if (indexName == null || indexName.isEmpty()) {
                // 如果知识库没有设置向量索引名称，则使用默认命名规则
                indexName = "kb_" + knowledgeBase.getId();
                // 更新知识库的向量索引名称
                knowledgeBase.setVectorIndexName(indexName);
                knowledgeBaseService.updateKnowledgeBase(knowledgeBase);
            }

            // 元数据信息
            Map<String, Object> metadata = new HashMap<>();
            metadata.put("id", document.getId().toString());
            metadata.put("title", document.getTitle());
            metadata.put("knowledge_base_id", document.getKnowledgeBaseId().toString());
            metadata.put("index_name", indexName);

            // 如果有文件信息，添加到元数据
            if (document.getFileName() != null) {
                metadata.put("file_name", document.getFileName());
                metadata.put("file_path", document.getFilePath());
            }

            // 创建Spring AI文档
            // 建立阶段式文档切分结构，如果单次切分报错超过设定的token则将这一块文档再次切分后再次入库
            DocumentSplitSaveUtil documentSplitSaveUtil = new DocumentSplitSaveUtil(500, vectorStore);
            documentSplitSaveUtil.splitAndSave(document, metadata);

            System.out.println("成功将文档(ID: " + document.getId() + ")添加到向量数据库，索引: " + indexName);
        } catch (Exception e) {
            System.err.println("将文档保存到向量数据库时出错: " + e.getMessage());
            e.printStackTrace();
        }
    }

    @Override
    public List<Document> getDocumentsByKnowledgeBaseId(Long knowledgeBaseId) {
        LambdaQueryWrapper<Document> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Document::getKnowledgeBaseId, knowledgeBaseId);
        return this.list(queryWrapper);
    }

    @Override
    public Document getDocumentById(Long id) {
        return this.getById(id);
    }

    @Override
    public Document updateDocument(Document document) {
        // 获取现有文档
        Document existingDoc = getById(document.getId());
        if (existingDoc == null) {
            throw new RuntimeException("文档不存在");
        }

        // 设置更新时间
        document.setUpdateTime(LocalDateTime.now());

        // 保留不变的字段
        document.setCreateTime(existingDoc.getCreateTime());
        document.setCreatedBy(existingDoc.getCreatedBy());

        // 如果前端没有传文件相关信息，保留原有信息
        if (document.getFileName() == null) {
            document.setFileName(existingDoc.getFileName());
        }
        if (document.getFilePath() == null) {
            document.setFilePath(existingDoc.getFilePath());
        }

        // 更新文档
        this.updateById(document);

        // 如果内容有更新且关联了知识库，更新向量数据库中的内容
        if (document.getKnowledgeBaseId() != null &&
                !document.getContent().equals(existingDoc.getContent())) {
            // 先删除旧的向量
            try {
                // 获取当前默认向量存储
                VectorStore vectorStore = aiModelInitService.getDefaultVectorStore();
                if (vectorStore != null) {
                    // 由于Spring AI的接口限制，目前可能需要根据元数据查询和删除
                    Filter.Expression filterExpression = new Filter.Expression(
                            Filter.ExpressionType.EQ,
                            new Filter.Key("id"),
                            new Filter.Value(document.getId().toString()));
                    vectorStore.delete(filterExpression);
                    // 然后保存新的向量
                    saveDocumentToVectorStore(document);
                }
            } catch (Exception e) {
                System.err.println("更新向量数据库时出错: " + e.getMessage());
                e.printStackTrace();
            }
        }

        return document;
    }

    @Override
    public boolean deleteDocument(Long id) {
        // 获取文档信息，用于后续删除向量存储中的数据
        Document document = getById(id);
        if (document != null && document.getKnowledgeBaseId() != null) {
            try {
                // 获取当前默认向量存储
                VectorStore vectorStore = aiModelInitService.getDefaultVectorStore();
                if (vectorStore != null) {
                    // 由于Spring AI的接口限制，目前可能需要根据元数据查询和删除
                    Filter.Expression filterExpression = new Filter.Expression(
                            Filter.ExpressionType.EQ,
                            new Filter.Key("id"),
                            new Filter.Value(document.getId().toString()));
                    vectorStore.delete(filterExpression);
                }
            } catch (Exception e) {
                System.err.println("从向量数据库删除文档时出错: " + e.getMessage());
                e.printStackTrace();
            }
        }

        // 从数据库中删除
        return this.removeById(id);
    }

    @Override
    public Page<Document> listDocuments(int page, int size, Long knowledgeBaseId) {
        Page<Document> pageParam = new Page<>(page, size);
        LambdaQueryWrapper<Document> queryWrapper = new LambdaQueryWrapper<>();

        // 如果指定了知识库ID，则按知识库ID过滤
        if (knowledgeBaseId != null) {
            queryWrapper.eq(Document::getKnowledgeBaseId, knowledgeBaseId);
        }

        // 按创建时间降序排序
        queryWrapper.orderByDesc(Document::getCreateTime);

        return this.page(pageParam, queryWrapper);
    }

    @Override
    public String addDocument(String content, Long knowledgeBaseId, String title) {
        try {
            if (content == null || content.isEmpty()) {
                return "文档内容不能为空";
            }

            // 创建新文档
            Document document = new Document();
            document.setContent(content);
            document.setTitle(title);
            document.setKnowledgeBaseId(knowledgeBaseId);

            // 保存文档
            saveDocument(document);

            return "文档添加成功，ID: " + document.getId();
        } catch (Exception e) {
            return "文档添加失败: " + e.getMessage();
        }
    }

    @Override
    public Document createDocumentFromFile(Map<String, Object> fileInfo, Long knowledgeBaseId, Long userId) {
        if (fileInfo == null || fileInfo.isEmpty()) {
            throw new IllegalArgumentException("文件信息不能为空");
        }

        // 从文件信息中提取数据
        String title = (String) fileInfo.get("originalFileName");
        String content = (String) fileInfo.get("content");
        String fileName = (String) fileInfo.get("originalFileName");
        String filePath = (String) fileInfo.get("filePath");

        if (content == null || content.isEmpty()) {
            throw new IllegalArgumentException("文件内容解析为空");
        }

        // 创建文档对象
        Document document = new Document();
        document.setTitle(title);
        document.setContent(content);
        document.setKnowledgeBaseId(knowledgeBaseId);
        document.setCreatedBy(userId);
        document.setFileName(fileName);
        document.setFilePath(filePath);

        // 保存文档
        return saveDocument(document);
    }
}